'''
Script to generate an openings database playing against gnu go.
'''
from pygo1963.goLogic.GoRules import GoRules
from pygo1963.model.Board import Board
from pygo1963.model.Move import Move
from pygo1963.model.Vertex import Vertex
from pygo1963.model import Constants
from subprocess import Popen, PIPE

#Amount of moves that should be registered
DEPTH = 2
MIN_SIZE = 7
MAX_SIZE = 8

rules = GoRules()

subpr = Popen(['gnugo', '--mode', 'gtp'], stdin=PIPE, stdout=PIPE)

def make_database(size, depth, color):
    """
    Given a depth, generates all possible boards with that amount of moves made.
    """    
    database = {}
    
    previous_row = [Board(size)]
    move = genmove(previous_row[0], color)
    database[previous_row[0].as_string()] = str(move)
    
    move_color = color
    
    while depth: 
        
        #swap colors
        move_color = get_move_color(color, move_color, depth)
                
        
        new_row = []
        for board in previous_row: #la profundidad anterior
            moves = rules.generate_valid_moves(board, move_color)
            
            for move in moves:
                board_copy = board.copy()
                board_copy.make_move(move)
                new_row.append(board_copy)
                
                key = board_copy.as_string()
                
                if not database.has_key(key):
                    move = genmove(board_copy, color)
                    database[key] = str(move)
                
            
        previous_row = new_row                
        
        print "done with depth", depth
        depth -= 1
        
    return database

def get_move_color(color, move_color, depth):
    
    if color == Constants.BLACK_COLOR and depth % 2:
        if move_color == Constants.BLACK_COLOR:
            return Constants.WHITE_COLOR
        else:
            return Constants.BLACK_COLOR
    
    elif color == Constants.WHITE_COLOR and not depth % 2:        
        if move_color == Constants.BLACK_COLOR:
            return Constants.WHITE_COLOR
        else:
            return Constants.BLACK_COLOR
    
    return move_color

def genmove(board, color):
    """ given a board state, asks gnugo to perform a move of the given color """
    
    subpr.stdin.write("clear_board\n")
    
    for move in board.as_move_list():        
        subpr.stdin.write('play %s\n' % move)
    
    subpr.stdin.write('genmove %s\n' % color)
    
    response = ''
    while not response:
        response = subpr.stdout.readline().lstrip('=').strip()
    
    if response == 'resign':
        response = 'pass'
    
    return Move(color, Vertex.from_string(response))


            
#MAIN PROGRAM
if __name__ == "__main__":
    
    for size in range(MIN_SIZE, MAX_SIZE + 1):    
        subpr.stdin.write("boardsize %d\n" % size )
        
        db = make_database(size, DEPTH, Constants.BLACK_COLOR)
        f = open('openings.black.%d.go' % size, 'w')
        f.write(repr(db))
        f.close()     
        
        f = open('openings.white.%d.go' % size, 'w')
        db = make_database(size, DEPTH, Constants.WHITE_COLOR)
        f.write(repr(db))
        f.close()
            